#!/bin/sh
#
# template.sh: Functions for dealing with release templates
#
# $Id: template.sh.in 761 2008-10-09 06:23:35Z enki $
# -------------------------------------------------------------------------
test $lib_template_sh || {

: ${prefix:="@prefix@"}     # default for prefix
: ${libdir:="${exec_prefix}/lib"}         # default value for libdir
: ${shlibdir:="${libdir}/sh"}
: ${localstatedir:="/var"}  # default value for localstatedir
: ${portsdir:="@prefix@/ports"}

#template_dir=$localstatedir/lib/tpl
template_dir=$portsdir/templates

. $shlibdir/fs.sh
. $shlibdir/shell/script.sh
. $shlibdir/data/text.sh

# template_list
# -------------------------------------------------------------------------
template_list()
{
  (cd "$template_dir" && fs_list)
}

# template_exists <name>
# -------------------------------------------------------------------------
template_exists()
{
  test -f "$template_dir/$1"
}

# template_mustexist <name>
# -------------------------------------------------------------------------
template_mustexist()
{
  test -f "$template_dir/$1" ||
  {
    error "No such template: $1"
    return 1
  }
}

# template_file <name>
# -------------------------------------------------------------------------
template_file()
{
  template_mustexist "$1" && echo "$template_dir/$1"
}

# template_script <name>
# -------------------------------------------------------------------------
template_script()
{
  sed -n '/^[-]\+$/ q; p' "$template_dir/$1"
}

# template_fn <name> <fn>
# -------------------------------------------------------------------------
template_fn()
{
  (eval "`template_script "$1"`"
   declare -f | sed -n "/^$2[ \t]*()[ \t]*$/ { :lp; n; /^}[ \t]*$/ q; /^{[ \t]*$/ b lp; s,^    ,,; s,^  ,,; p; b lp; }")
}

# template_create <name> [strip flags]
# -------------------------------------------------------------------------
template_create()
{
  if template_exists "$1"
  then
    error "Template '$1' already exists."
    return 1
  fi

  touch "$template_dir/$1"
  script_setvar "$template_dir/$1" "strip" "${2-x}"
  echo "----------------------------------------------------------------------------" >>$template_dir/$1
  template_add "$1" "base/sw-utils"
}

# template_strip <name>
# -------------------------------------------------------------------------
template_strip()
{
  template_mustexist "$1" && script_getvar "$template_dir/$1" "strip"
}

# template_vars <name>
# -------------------------------------------------------------------------
template_vars()
{
  template_mustexist "$1" &&
  grep "^[0-9A-Za-z_]\+_[0-9A-Za-z_]\+=" "$template_dir/$1"
}

# template_pkglist <name> [tree]
# -------------------------------------------------------------------------
template_pkglist()
{
  template_mustexist "$1" &&
  if test -n "$2"
  then
    echo "$2" | sed 's,^\t*,,'
  else
    sed -n "/^--/ {
      :lp; n
      s,^\t*,,
      p; b lp; q
    }" "$template_dir/$1"
  fi
}

# template_pkgtree <name>
# -------------------------------------------------------------------------
template_pkgtree()
{
  template_mustexist "$1" &&
  sed -n "/^--/ {
    :lp
    n
    p
    b lp
    q
  }" "$template_dir/$1"
}

# template_contains <name> <category/package> [tree]
# -------------------------------------------------------------------------
template_contains()
{
  template_mustexist "$1" &&
  if test -n "$3"; then
    echo "$3" | grep -qP "^\t*${2%/*}/${2#*/}\$"
  else
    grep -qP "^\t*${2%/*}/${2#*/}\$" "$template_dir/$1"
  fi
}

# template_mktree <name> <category/package> <indent>
# -------------------------------------------------------------------------
template_mktree()
{
  array_isin 'pkglist' $2 && return 1
  array_push 'pkglist' $2

  local cat=${2%/*} pkg=${2#*/}

  if ! is_port "$cat/$PKG"
  then
    msg "The port '$cat/$PKG' does not exist."
    return 1
  fi

  local deps=`port_deps "$cat" "$PKG"`

  echo "$3"$2

  for dep in $deps; do
    template_mktree "$1" $dep "$3	"
  done
}

# template_add <name> <category/package> [parent]
# -------------------------------------------------------------------------
template_add()
{
  template_mustexist "$1" &&
  {
    local packages=`template_pkgtree "$1"`

    template_contains "$1" "$2" "$packages" && return 2

    if test -n "$3"
    then
      local indent=`template_indent "$1" "$3" "$packages"` || return 3
      indent="$indent$tabstop"
    fi

    local pkglist=`template_pkglist "$1" "$packages"`
    local tree=`template_mktree "$1" "$2" "$indent"`

    if test -n "$3"
    then
      local after

      if ! local children=`template_deps "$1" "$3" "$packages"`; then
        return 4
      else
        after=`echo "$children" | tail -n1`
      fi

      test -z "$after" && after="$3"

      text_insert_after "$tree" "$after" "$template_dir/$1"
    else
      text_append "$tree" "$template_dir/$1"
    fi

    msg "Added package '$2' to '$1'."
  }
}

# template_indent <name> <category/package> [tree]
# -------------------------------------------------------------------------
template_indent()
{
  template_mustexist "$1" &&
  {
    local packages indent

    test -n "$3" && packages="$3" || packages=`template_pkgtree "$1"`

    indent=$(echo "$packages" | sed -n "\,^\t*$2\$, {
      s,^\(\t*\)$2,\1, p
      q
    }
    \$ i\
-
")
    test "$indent" = "-" && return 1
    echo "$indent"
  }
}

# template_level <name> <category/package>
# -------------------------------------------------------------------------
template_level()
{
  template_mustexist "$1" &&
  {
    local indent=`template_indent "$1" "$2"` && echo "${#indent}"
  }
}

# template_children <name> [category/package]
# -------------------------------------------------------------------------
template_children()
{
  template_mustexist "$1" &&
  {
    if test -n "$2"
    then
      local indent=`template_indent "$1" "$2"` || return 2

      template_pkgtree "$1" |
      sed -n "\,^$indent$2, {
        n
        :lp
        /^$indent\t/! q
        /^$indent\t\t/! s,^$indent\t,, p
        n
        b lp
      }"
    else
      template_pkgtree "$1" | sed -n "\,\t,! p"
    fi
  }
}

# template_deps <name> [category/package]
# -------------------------------------------------------------------------
template_deps()
{
  template_mustexist "$1" &&
  {
    if test -n "$2"; then
      local indent=`template_indent "$1" "$2"` || return 1
      template_pkgtree "$1" | sed -n "\,^$indent$2, {
        n
        :lp
        /^$indent\t/! q
        s,^$indent\t,, p
        n
        b lp
      }"
    else
      template_pkgtree "$1"
    fi
  }
}

# template_recurse <name> [category/package] [level]
# -------------------------------------------------------------------------
template_recurse()
{
  template_mustexist "$1" &&
  {
    test -n "$2" && ! template_contains "$1" "$2" && return 1
    local IFS="" start strip upto=${3-0}

    if test $((upto)) = 0; then
      template_deps "$1" ${2+"$2"}
      return $?
    elif test $((upto)) = 1; then
      template_children "$1" ${2+"$2"}
      return $?
    fi

    template_pkgtree "$1" | while read pkgcat; do
      local flat=${pkgcat##*	}
      local indent=${pkgcat%$flat}
      local level=${#indent}
      if test -z "$start"; then
        if [ "$flat" = "$2" ]; then
          start=$((level))
          strip="$indent	"
        elif test -z "$2"; then
          start=$((level - 1))
          strip="$indent"
        fi
      elif test $((level)) -gt $((start))
      then
        test $((upto)) != 0 &&
        test $((level - start)) -gt $((upto)) &&
        continue
        echo ${pkgcat#$strip}
      else
        break
      fi
    done
  }
}

# --- eof ---------------------------------------------------------------------
lib_template_sh=:;}
